﻿using Treca.PushMessage.Base.MessageEvent;
using Treca.PushMessage.Business;
using Treca.Util;
using Treca.Web.Areas.Base_SysManage.Controllers;
using Senparc.Weixin.MP.AdvancedAPIs;
using Senparc.Weixin.MP.AdvancedAPIs.TemplateMessage;
using Senparc.Weixin.MP.Containers;
using Senparc.Weixin.MP.Entities.Request;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace Treca.PushMessage.Base
{

    public class PMObj
    {
        public string appid { get; set; }
        public string servicetype { get; set; }
    }

    public class PMMSObj
    {
        public string appid { get; set; }
        public string servicetype { get; set; }
    }

    public class WeiXinAppMS : PMMSObj
    {
        public XDocument xml { get; set; }
        public PostModel postModel { get; set; }
    }

    public class WeiXinApp:PMObj
    {
        public string servicecode { get; set; }
        public string templeteId { get; set; }
        public string openId { get; set; }
        public string userId { get; set; }
        public object messageobj { get; set; }
        //
        // 摘要:
        //     小程序AppId
        public string wxappid { get; set; }
        //
        // 摘要:
        //     路径，如：index?foo=bar
        public string pagepath { get; set; }
    }

    public class PMService
    { 
        /// <summary>
        /// 服务代码
        /// </summary>
        public String Id { get; set; }
        /// <summary>
        /// 服务代码
        /// </summary>
        public String servicecode { get; set; }

        /// <summary>
        /// 消息服务名称
        /// </summary>
        public String servicename { get; set; }

        /// <summary>
        /// 消息服务名称
        /// </summary>
        public String servicetype { get; set; }

        /// <summary>
        /// AppId
        /// </summary>
        public String appid { get; set; }

        /// <summary>
        /// AppSecret
        /// </summary>
        public String appsecret { get; set; }

        /// <summary>
        /// EncodingAESKey
        /// </summary>
        public String encodingaeskey { get; set; }

        /// <summary>
        /// Token
        /// </summary>
        public String token { get; set; }
    }

    public class PMServiceContainer : ISingleDependency, IPMServiceContainer
    {
        private Dictionary<string, IPMService> costDeviceDict = new Dictionary<string, IPMService>();

        public PMServiceContainer()
        {
            Ims_messageserviceBusiness messageserviceBusiness = AutofacHelper.GetScopeService<Ims_messageserviceBusiness>();
            var servicelist = messageserviceBusiness.GetIQueryable().Where(t => t.StatusFlag == "1").ToList();
            foreach (var service in servicelist)
            {
                PMService mService = new PMService();
                mService.Id = service.Id;
                mService.appid = service.appid;
                mService.appsecret = service.appsecret;
                mService.token = service.token;
                mService.servicetype = service.servicetype;
                mService.servicename = service.servicename;
                mService.encodingaeskey = service.encodingaeskey;
                var res = AddService(mService);
                if (!res.Success)
                {
                    LogHelper.WriteLog_LocalTxt("服务注册失败：" + service.appid + " " + service.servicename + " 服务名" + service.servicename);
                }
            }
        }

        public AjaxResult AddService(PMService pmservice)
        {
            try
            {
                if (!costDeviceDict.ContainsKey(pmservice.appid))
                {
                    if (pmservice.servicetype == "WeiXinApp")
                    {
                        AccessTokenContainer.RegisterAsync(pmservice.appid, pmservice.appsecret).Wait();
                        WeiXinAppDevice weiXinAppDevice = new WeiXinAppDevice(pmservice);
                        costDeviceDict.Add(pmservice.appid, weiXinAppDevice);
                    }
                    else if (pmservice.servicetype == "WeiXinOfficialAccounts")
                    {
                        AccessTokenContainer.RegisterAsync(pmservice.appid, pmservice.appsecret).Wait();
                        WeiXinOfficialAccountsDevice weiXinAppDevice = new WeiXinOfficialAccountsDevice(pmservice);
                        costDeviceDict.Add(pmservice.appid, weiXinAppDevice);
                    }
                    else
                    {
                        return AjaxHelper.Success("设备类型错误");
                    }
                    return AjaxHelper.Success("注册成功");
                }
                else
                {
                    return AjaxHelper.Success("已经注册");
                }
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog_LocalTxt("消息服务注册：" + ExceptionHelper.GetExceptionAllMsg(ex));
                return AjaxHelper.Error("消息服务注册失败(具体原因查询日志)" + ex.Message);
            }
        }


        public AjaxResult AddServiceById(string Id)
        {
            try
            {
                Ims_messageserviceBusiness messageserviceBusiness = AutofacHelper.GetScopeService<Ims_messageserviceBusiness>();
                var servicelist = messageserviceBusiness.GetIQueryable().Where(t => t.StatusFlag == "1").Where(t => t.Id == Id).ToList();
                foreach (var service in servicelist)
                {
                    PMService mService = new PMService();
                    mService.Id = service.Id;
                    mService.appid = service.appid;
                    mService.appsecret = service.appsecret;
                    mService.token = service.token;
                    mService.servicetype = service.servicetype;
                    mService.servicename = service.servicename;
                    mService.encodingaeskey = service.encodingaeskey;
                    var res = AddService(mService);
                    if (!res.Success)
                    {
                        LogHelper.WriteLog_LocalTxt("服务注册失败：" + service.appid + " " + service.servicename + " 服务名" + service.servicename);
                    }
                    return res;
                }
                return AjaxHelper.Error("服务不存在");
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog_LocalTxt("消息服务注册：" + ExceptionHelper.GetExceptionAllMsg(ex));
                return AjaxHelper.Error("消息服务注册失败(具体原因查询日志)" + ex.Message);
            }
        }
        public AjaxResult PushMessage(PMObj currency)
        {
            if (costDeviceDict == null) return AjaxHelper.Error("容器未初始化");
            if (!costDeviceDict.ContainsKey(currency.appid))
            {
                return AjaxHelper.Error("服务不存在,请添加服务");
            }
            IPMService PMSevice = costDeviceDict[currency.appid];
            return PMSevice.PushMessage(currency);
        }

        public AjaxResult GetMessage(PMMSObj currency)
        {
            if (costDeviceDict == null) return AjaxHelper.Error("容器未初始化");
            if (!costDeviceDict.ContainsKey(currency.appid))
            {
                AjaxHelper.Error("服务不存在,请添加服务");
            }
            IPMService PMSevice = costDeviceDict[currency.appid];
            return PMSevice.GetMessage(currency);
        }
    }

    /*扣款设备*/
    public interface IPMService
    {
        String DeviceType { get; }
        AjaxResult PushMessage(PMObj currency);
        AjaxResult GetMessage(PMMSObj currency);
    }

    public class WeiXinAppDevice: IPMService
    {
        public WeiXinAppDevice(PMService _service)
        {
            service = _service;
        }
        public PMService service { get; }
        public String DeviceType => "WeiXinApp";
        Ims_messagetempleteBusiness _MessagetempleteBusiness { get => AutofacHelper.GetScopeService<Ims_messagetempleteBusiness>(); }
        Ims_messageuserBusiness _MessageuserBusiness { get => AutofacHelper.GetScopeService<Ims_messageuserBusiness>(); }
        public AjaxResult PushMessage(PMObj weixinappmes)
        {
            WeiXinApp weiXinApp = (WeiXinApp)weixinappmes;
            //var templete = _MessagetempleteBusiness.GetIQueryable().Where(t => t.templeteId == weiXinApp.templeteId && t.serviceId == service.Id).FirstOrDefault();
            //if (templete.IsNullOrEmpty())
            //{
            //    return AjaxHelper.Error("消息模板不存在");
            //}
            var useropen = _MessageuserBusiness.GetIQueryable().Where(t => t.userId == weiXinApp.userId && t.serviceAppId == weiXinApp.appid).FirstOrDefault();
            if (!useropen.IsNullOrEmpty())
                weiXinApp.openId = useropen.userOpenId;
            string access_token = AccessTokenContainer.GetAccessTokenResult(service.appid).access_token;
            TempleteModel_MiniProgram templeteModel_Mini = new TempleteModel_MiniProgram();
            if (!weiXinApp.wxappid.IsNullOrEmpty())
            {
                templeteModel_Mini.appid = weiXinApp.wxappid;
                templeteModel_Mini.pagepath = weiXinApp.pagepath;
            }
            else
            {
                templeteModel_Mini = null;
            }
            var res = TemplateApi.SendTemplateMessage(access_token, weiXinApp.openId, weiXinApp.templeteId, "", weiXinApp.messageobj, templeteModel_Mini, 10000);
            if (res.errcode == 0)
            {
                return AjaxHelper.Success();
            }
            else
            {
                return AjaxHelper.Error(res.errmsg);
            }
        }

        public AjaxResult GetMessage(PMMSObj weixinappmes)
        {
            WeiXinAppMS weiXinApp = (WeiXinAppMS)weixinappmes;
            //自定义MessageHandler，对微信请求的详细判断操作都在这里面。
            var messageHandler = new CustomMessageHandler(weiXinApp.xml, weiXinApp.postModel);//接收消息

            messageHandler.Execute();//执行微信处理过程

            return AjaxHelper.Success(messageHandler.ResponseDocument);
        }

    }

    public class WeiXinOfficialAccountsDevice : IPMService
    {
        public WeiXinOfficialAccountsDevice(PMService _service)
        {
            service = _service;
        }
        public PMService service { get; }
        public String DeviceType => "WeiXinOfficialAccounts";
        Ims_messagetempleteBusiness _MessagetempleteBusiness { get => AutofacHelper.GetScopeService<Ims_messagetempleteBusiness>(); }
        Ims_messageuserBusiness _MessageuserBusiness { get => AutofacHelper.GetScopeService<Ims_messageuserBusiness>(); }
        public AjaxResult PushMessage(PMObj weixinappmes)
        {
            WeiXinApp weiXinApp = (WeiXinApp)weixinappmes;
            //var templete = _MessagetempleteBusiness.GetIQueryable().Where(t => t.templeteId == weiXinApp.templeteId && t.serviceId == service.Id).FirstOrDefault();
            //if (templete.IsNullOrEmpty())
            //{
            //    return AjaxHelper.Error("消息模板不存在");
            //}
            var useropen = _MessageuserBusiness.GetIQueryable().Where(t => t.userId == weiXinApp.userId && t.serviceAppId == weiXinApp.appid).FirstOrDefault();
            if (!useropen.IsNullOrEmpty())
                weiXinApp.openId = useropen.userOpenId;
            string access_token = AccessTokenContainer.GetAccessTokenResult(service.appid).access_token;
            TempleteModel_MiniProgram templeteModel_Mini = new TempleteModel_MiniProgram();
            if (!weiXinApp.wxappid.IsNullOrEmpty())
            {
                templeteModel_Mini.appid = weiXinApp.wxappid;
                templeteModel_Mini.pagepath = weiXinApp.pagepath;
            }
            else
            {
                templeteModel_Mini = null;
            }
            var res = TemplateApi.SendTemplateMessage(access_token, weiXinApp.openId, weiXinApp.templeteId, "", weiXinApp.messageobj, templeteModel_Mini, 10000);
            if (res.errcode == 0)
            {
                return AjaxHelper.Success();
            }
            else
            {
                return AjaxHelper.Error(res.errmsg);
            }
        }

        public AjaxResult GetMessage(PMMSObj weixinappmes)
        {
            WeiXinAppMS weiXinApp = (WeiXinAppMS)weixinappmes;
            //自定义MessageHandler，对微信请求的详细判断操作都在这里面。
            var messageHandler = new CustomMessageHandler(weiXinApp.xml, weiXinApp.postModel);//接收消息

            messageHandler.Execute();//执行微信处理过程

            return AjaxHelper.Success(messageHandler.ResponseDocument);
        }


    }
}

